iT邦幫忙

2022 iThome 鐵人賽

DAY 5
1

前一天我們談到了可以從三大法人買賣超,瞭解機構法人在臺股的買賣動向。由於法人資金部位大並且擁有資訊不對稱的優勢,就長期而言,通常法人是市場的贏家,散戶則是市場的輸家,因此我們可以將散戶視為市場的反指標,如果要觀察散戶對股市的看法,可以參考股市的融資融券餘額增減。

信用交易

在臺灣股票市場,股票交易可以分成「現股交易」和「信用交易」。現股交易就用現金買賣股票;信用交易又分為「融資」和「融券」。用比較白話的說法,融資是向券商借錢買股票;融券是向券商借股票來賣出。投資人必須向券商申請開立信用交易帳戶才能進行信用交易,就交易目的而言,融資是為了做多,而融券則是為了放空。

融資融券餘額

在臺灣證券市場,法人不能使用融資融券交易,所以融資融券的餘額與增減通常被解讀散戶指標。下圖是 2022 年初至 8 月 31 日止的大盤融資與融券餘額,融資代表看空,融券代表看空,所以融資與融券餘額大多時候是呈現反向關係。

https://ithelp.ithome.com.tw/upload/images/20220905/20150150Ag8QvgwTQ2.png

Source:臺灣證券交易所

當融資餘額增加,代表散戶看多,後續股市下跌的機會較大;而融券餘額增加,代表散戶看空,後續股市上漲的機會較大。因為融資餘額增加代表散戶進場,容易造成籌碼不穩定,如果大戶不願意進場幫散戶抬轎,股市就不容易上漲;融券餘額增加代表散戶看壞股市,如果有軋空行情,融券回補就會變成股市上漲的燃料。

融資斷頭是短線止跌訊號

融資有擔保維持率,當股票下跌造成整戶擔保維持率不足時,券商就會發出融資追繳通知,必須在期限內完成補錢,如果不補足差額,就會被券商強制賣出,這就是俗稱的「斷頭」。

當大盤出現連續下跌,容易造成融資維持率不足,這時過多的融資就會變成股市加速下跌的助力,因為市場上會有融資的停損賣壓,可能引發融資斷頭潮,形成「融資多殺多」、「散戶人踩人」的狀況。當融資減少時,代表散戶出場,籌碼回歸到法人或大戶手中,短線上,股市就有機會暫時止跌。

有些資訊廠商會提供「大盤融資維持率」的數據。大盤融資維持率 = 所有融資股票市值 / 大盤融資餘額 =(所有融資股數 x 股票的股價 / 大盤融資餘額。融資買進股票時的維持率是 166%,當融資維持率低於 130% 時,券商就會發出追繳令,如果當大盤融資維持率逼近 130% 時,則代表市場上的融資散戶幾乎都已經斷頭了,因此大盤融資維持率可以作為一個參考的指標。

下圖是 2022 年初至 8 月 31 日止的大盤融資餘額,可以看出融資餘額與加權指數有正向關係,2022 上半年加權指數一路下跌,市場上的融資餘額也不斷地減少。

https://ithelp.ithome.com.tw/upload/images/20220905/20150150zyzGzzIWje.png

Source:臺灣證券交易所

雖然 融資融券餘額 一般被視為散戶指標,但仍須注意的是,市場上也有非屬法人的主力大戶使用融資來放大槓桿加速獲利,因此我們在參考這個指標時,仍需搭配其他數據相互確認。

查詢集中市場融資融券餘額

在證交所網站的 融資融券餘額 頁面,可以按日查詢集中市場的信用交易統計。

證交所首頁 > 交易資訊 > 融資融券與可借券賣出額度 > 融資融券餘額

在「融資融券餘額」頁面,選取「查詢日期」和「分類項目」後按下「查詢」。分類項目選擇「信用交易統計」可查詢大盤統計,選擇「全部」會列出所有上市股票融資融券彙總。

https://ithelp.ithome.com.tw/upload/images/20220905/201501508e7tNfxL4R.png

點擊「列印 / HTML」連結,瀏覽器會開新分頁將資訊輸出成可列印的 HTML 頁面。假設資料日期為「民國 111 年 07 月 01 日」,我們會得到以下 URL:

https://www.twse.com.tw/exchangeReport/MI_MARGN?response=html&date=20220701&selectType=MS

以上 URL 可設定的參數如下:

  • response:回應資料的格式。指定 html 輸出 HTML 文件;改為 csv 可以另存 CSV 檔案;設定成 json 或不指定則回應 JSON 格式資料。
  • date:資料日期。接受的日期格式為 yyyyMMdd,如 20220701
  • selectType:分類項目。MS 為「信用交易統計」;ALL 為「全部」。

我們將 URL 查詢參數改為 response=json&dayDate=20220701&selectType=ALL,證交所就會以 JSON 格式資料回應 2022 年 7 月 1 日的信用交易統計:

{
  "stat": "OK",
  "creditTitle": "111年07月01日 信用交易統計",
  "creditFields": [
    "項目",
    "買進",
    "賣出",
    "現金(券)償還",
    "前日餘額",
    "今日餘額"
  ],
  "creditList": [
    [
      "融資(交易單位)",
      "299,709",
      "508,441",
      "10,846",
      "7,462,957",
      "7,243,379"
    ],
    [
      "融券(交易單位)",
      "76,277",
      "88,013",
      "1,222",
      "509,726",
      "520,240"
    ],
    [
      "融資金額(仟元)",
      "8,576,037",
      "17,191,501",
      "1,662,750",
      "206,723,788",
      "196,445,574"
    ]
  ],
  ......
}

在信用交易統計中,通常一個交易單位代表 1000 股,也就是一張。融券是借股票,所以統計的是「交易單位」;融資則區分出「交易單位」和「金額」。由於大盤統計的是市場上所有股票,而不同公司的股票價值是不等的,因此在融資餘額的數據,我們主要會觀察融資金額,而不是融資張數。

實作:取得集中市場融資融券餘額

開啟 src/scraper/twse-scraper.service.ts 檔案,在 TwseScraperService 加入 fetchMarginTransactions() 方法,並指定 date 參數,表示要取得集中市場集中市場融資融券餘額的日期:

import * as cheerio from 'cheerio';
import * as iconv from 'iconv-lite';
import * as numeral from 'numeral';
import { DateTime } from 'luxon';
import { Injectable } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { firstValueFrom } from 'rxjs';

@Injectable()
export class TwseScraperService {
  constructor(private httpService: HttpService) {}

  ...

  async fetchMarginTransactions(date: string) {
    // 將 `date` 轉換成 `yyyyMMdd` 格式
    const formattedDate = DateTime.fromISO(date).toFormat('yyyyMMdd');

    // 建立 URL 查詢參數
    const query = new URLSearchParams({
      response: 'json',     // 指定回應格式為 JSON
      date: formattedDate,  // 指定資料日期
      selectType: 'MS',     // 指定分類項目為信用交易統計
    });
    const url = `https://www.twse.com.tw/en/exchangeReport/MI_MARGN?${query}`;

    // 取得回應資料
    const responseData = await firstValueFrom(this.httpService.get(url))
      .then(response => (response.data.stat === 'OK') ? response.data : null);

    // 若該日期非交易日或尚無信用交易統計則回傳 null
    if (!responseData) return null;
    if (!responseData.creditList.length) return null;

    // 整理回應資料
    const raw = responseData.creditList
      .map(data => data.slice(1)).flat()  // 取出買賣金額並減少一層陣列嵌套
      .map(data => numeral(data).value() || +data); // 轉為數字格式

    const [
      marginPurchase,           // 融資(交易單位)-買進
      marginSale,               // 融資(交易單位)-賣出
      cashRedemption,           // 融資(交易單位)-現金(券)償還
      marginBalancePrev,        // 融資(交易單位)-前日餘額
      marginBalance,            // 融資(交易單位)-今日餘額
      shortCovering,            // 融券(交易單位)-買進
      shortSale,                // 融券(交易單位)-賣出
      stockRedemption,          // 融券(交易單位)-現金(券)償還
      shortBalancePrev,         // 融券(交易單位)-前日餘額
      shortBalance,             // 融券(交易單位)-今日餘額
      marginPurchaseValue,      // 融資金額(仟元)-買進
      marginSaleValue,          // 融資金額(仟元)-賣出
      cashRedemptionValue,      // 融資金額(仟元)-現金(券)償還
      marginBalanceValuePrev,   // 融資金額(仟元)-前日餘額
      marginBalanceValue,       // 融資金額(仟元)-今日餘額
    ] = raw;

    // 計算融資餘額增減(交易單位)
    const marginChange = marginBalance - marginBalancePrev;

    // 計算融資餘額增減(仟元)
    const marginChangeValue = marginBalanceValue - marginBalanceValuePrev;

    // 計算融券餘額增減(交易單位)
    const shortChange = shortBalance - shortBalancePrev;

    return {
      date,
      marginBalance,
      marginBalanceChange,
      marginBalanceValue,
      marginBalanceValueChange,
      shortBalance,
      shortBalanceChange,
    };
  }
}

fetchMarginTransactions() 方法中,需要指定 date 參數,表示要取得融資融券餘額的日期。我們定義回傳的物件欄位包含如下:

  • date:日期
  • marginBalance:融資餘額(張)
  • marginBalanceChange:融資餘額(張)
  • marginBalanceValue:融資餘額(仟元)
  • marginBalanceValueChange:融資餘額增減(仟元)
  • shortBalance:融券餘額增減(張)
  • shortBalanceChange:融券餘額增減(張)

完成後,我們只要呼叫 TwseScraperServicefetchMarginTransactions() 方法,就可以按日期取得集中市場融資融券餘額。以日期 2022-07-01 為例:

{
  date: '2022-07-01',
  marginBalance: 7243379,
  marginBalanceChange: -219578,
  marginBalanceValue: 196445574,
  marginBalanceValueChange: -10278214,
  shortBalance: 520240,
  shortBalanceChange: 10514
}

查詢櫃買市場融資融券餘額

在櫃買中心網站的 上櫃股票融資融券餘額 頁面,可以按日查詢上櫃股票融資融券餘額。

櫃買中心首頁 > 上櫃 > 融資融券 > 融資融券餘額表

在「上櫃股票融資融券餘額」頁面選取「資料日期」後,就會列出上櫃股票融資融券餘額統計。

https://ithelp.ithome.com.tw/upload/images/20220905/20150150DJUQpzzKcS.png

點擊「列印/匯出HTML」連結,瀏覽器會開新分頁將資訊輸出成可列印的 HTML 頁面。假設資料日期為「111/07/01」,我們會得到以下 URL:

https://www.tpex.org.tw/web/stock/margin_trading/margin_balance/margin_bal_result.php?l=zh-tw&o=htm&d=111/07/01&s=0,asc

以上 URL 可設定的參數如下:

  • l:輸出資料的語系。zh-tw 為正體中文;en-us 為英文。
  • o:資料輸出的格式。指定 htm 表示輸出 HTML 文件;改為 csv 可以另存 CSV 檔案;設定成 json 或不指定則回應 JSON 格式資料。
  • d:資料日期。接受 民國年/月/日 的日期格式。需要注意,若 l 參數指定為 en-us,則 d 參數需改成 西元年/月/日 的日期格式。
  • s:指定欄位依照升冪或降冪排序。例如 0,asc 是按代號升冪排序;1,desc 則按名稱降冪排序,依此類推。

我們將 URL 查詢參數改為 l=zh-tw&o=json&d=111/07/01,櫃買中心就會以 JSON 格式資料回應 2022 年 7 月 1 日上櫃股票融資融券餘額:

{
  "reportDate": "111/07/01",
  "iTotalRecords": 764,
  "aaData": [
    "00679B",
    "元大美債20年",
    "588",
    "99",
    "0",
    "0",
    "687",
    "0",
    "0.26",
    "256,673",
    "0",
    "0",
    "0",
    "0",
    "0",
    "0",
    "0.0",
    "256,673",
    "0",
    "",
    ...
  ],
  "tfootData_one": [
    "1,646,783",
    "59,773",
    "105,349",
    "3,378",
    "1,597,829",
    "",
    "",
    "",
    "80,440",
    "12,314",
    "19,566",
    "177",
    "73,011"
  ],
  "tfootData_two": [
    "61,565,604",
    "2,331,350",
    "5,006,438",
    "452,166",
    "58,438,350"
  ]
}

簡化了櫃買中心回傳的 JSON 格式資料,在 aaData 欄位可以得到所有上櫃股票的融資融券餘額。因為我們要查詢的是櫃買市場整體的融資融券餘額統計,所以只需要關注 tfootData_onetfootData_two 欄位的數字即可。

  • tfootData_one 欄位內的資料依序表示:融資(交易單位)-前日餘額、融資(交易單位)-買進、融資(交易單位)-賣出、融資(交易單位)-現金(券)償還、融資(交易單位)-今日餘額、融券(交易單位)-前日餘額、融券(交易單位)-買進、融券(交易單位)-賣出、融券(交易單位)-現金(券)償還、融券(交易單位)-今日餘額。
  • tfootData_two 欄位內的資料依序表示:融資金額(仟元)-前日餘額、融資金額(仟元)-買進、融資金額(仟元)-賣出、融資金額(仟元)-現金(券)償還、融資金額(仟元)-今日餘額。

實作:取得櫃買市場融資融券餘額

開啟 src/scraper/tpex-scraper.service.ts 檔案,在 TpexScraperService 加入 fetchMarginTransactions() 方法,並指定 date 參數,表示要取得櫃買市場融資融券餘額的日期:

import * as numeral from 'numeral';
import { DateTime } from 'luxon';
import { Injectable } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { firstValueFrom } from 'rxjs';

@Injectable()
export class TpexScraperService {
  constructor(private httpService: HttpService) {}

  ...

  async fetchMarginTransactions(date: string) {
    // `date` 轉換成 `民國年/MM/dd` 格式
    const dt = DateTime.fromISO(date);
    const year = dt.get('year') - 1911;
    const formattedDate = `${year}/${dt.toFormat('MM/dd')}`;

    // 建立 URL 查詢參數
    const query = new URLSearchParams({
      l: 'zh-tw',       // 指定語系為正體中文
      d: formattedDate, // 指定日期
      o: 'json',        // 指定回應格式為 JSON
    });
    const url = `https://www.tpex.org.tw/web/stock/margin_trading/margin_balance/margin_bal_result.php?${query}`;

    // 取得回應資料
    const responseData = await firstValueFrom(this.httpService.get(url))
      .then(response => (response.data.iTotalRecords > 0) && response.data);

    // 若該日期非交易日或尚無成交資訊則回傳 null
    if (!responseData) return null;

    // 整理回應資料
    const raw = [
      ...responseData.tfootData_one,
      ...responseData.tfootData_two
    ]  // 取出融資融券統計
      .map(data => numeral(data).value()) // 轉為數字格式
      .filter(data => data);  // 移除 null 值

    const [
      marginBalancePrev,        // 融資(交易單位)-前日餘額
      marginPurchase,           // 融資(交易單位)-買進
      marginSale,               // 融資(交易單位)-賣出
      cashRedemption,           // 融資(交易單位)-現金(券)償還
      marginBalance,            // 融資(交易單位)-今日餘額
      shortBalancePrev,         // 融券(交易單位)-前日餘額
      shortCovering,            // 融券(交易單位)-買進
      shortSale,                // 融券(交易單位)-賣出
      stockRedemption,          // 融券(交易單位)-現金(券)償還
      shortBalance,             // 融券(交易單位)-今日餘額
      marginBalanceValuePrev,   // 融資金額(仟元)-前日餘額
      marginPurchaseValue,      // 融資金額(仟元)-買進
      marginSaleValue,          // 融資金額(仟元)-賣出
      cashRedemptionValue,      // 融資金額(仟元)-現金(券)償還
      marginBalanceValue,       // 融資金額(仟元)-今日餘額
    ] = raw;

    // 計算融資餘額增減(交易單位)
    const marginBalanceChange = marginBalance - marginBalancePrev;

    // 計算融資餘額增減(仟元)
    const marginBalanceValueChange = marginBalanceValue - marginBalanceValuePrev;

    // 計算融券餘額增減(交易單位)
    const shortBalanceChange = shortBalance - shortBalancePrev;

    return {
      date,
      marginBalance,
      marginBalanceChange,
      marginBalanceValue,
      marginBalanceValueChange,
      shortBalance,
      shortBalanceChange,
    };
  }
}

fetchMarginTransactions() 方法中,需要指定 date 參數,表示要取得融資融券餘額的日期。我們定義回傳的物件欄位包含如下:

  • date:日期
  • marginBalance:融資餘額(張)
  • marginBalanceChange:融資餘額(張)
  • marginBalanceValue:融資餘額(仟元)
  • marginBalanceValueChange:融資餘額增減(仟元)
  • shortBalance:融券餘額增減(張)
  • shortBalanceChange:融券餘額增減(張)

完成後,我們只要呼叫 TpexScraperServicefetchMarginTransactions() 方法,就可以按日期櫃買市場融資融券餘額。以日期 2022-07-01 為例:

{
  date: '2022-07-01',
  marginBalance: 1597829,
  marginBalanceChange: -48954,
  marginBalanceValue: 58438350,
  marginBalanceValueChange: -3127254,
  shortBalance: 73011,
  shortBalanceChange: -7429
}

本日小結

  • 大盤融資融券餘額通常被視為散戶指標。
  • 當融資餘額增加,代表散戶看多,後續股市下跌的機會較大。
  • 當融券餘額增加,代表散戶看空,後續股市上漲的機會較大。
  • 大盤連續下跌造成融資斷頭出場,可視為短線止跌的訊號。
  • 瞭解如何在證交所網站上查詢並實作取得集中市場融資融券餘額的方法。
  • 瞭解如何在櫃買中心網站上查詢並實作取得櫃買市場融資融券餘額的方法。

Node.js 量化投資全攻略:從資料收集到自動化交易系統建構實戰
本系列文已正式出版為《Node.js 量化投資全攻略:從資料收集到自動化交易系統建構實戰》。本書新增了全新內容和實用範例,為你提供更深入的學習體驗!歡迎參考選購,開始你的量化投資之旅!
天瓏網路書店連結:https://www.tenlong.com.tw/products/9786263336070


上一篇
Day 04 - 法人主導的市場:三大法人買賣超
下一篇
Day 06 - 法人期貨動向:三大法人臺股期貨未平倉
系列文
從 Node.js 開發者到量化交易者:打造屬於自己的投資系統31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言